#ifndef MSG_H
#define MSG_H

#include <sys/ipc.h>
#include <sys/msg.h>
#include "testbase.h"

class Msg : public TestBase {
    struct my_msg {
        long type;
        char data[1024];
    };

public:
    Msg(int argc, char** argv) : TestBase(argc, argv), flag(-1) {
        memset(&sendmsg, 0, sizeof(my_msg));
        memset(&readmsg, 0, sizeof(my_msg));

        key_t key = ftok("/temp", 1);
        msgId = msgget(key, IPC_CREAT | 0777);
        valid = msgId!=-1;
        if(valid) puts("msgget succeed");
        else puts("msgget failed");

        if(argc_ > 1) flag = std::stoi(argv[1]);
    }

    ~Msg() {
        if(!valid) return;
        int ret = msgctl(msgId, IPC_RMID, nullptr);
        if(ret == 0) puts("msgctl succeed");
        else puts("msgctl failed");
    }

    bool read(int type) {
        int len = msgrcv(msgId, &readmsg, sizeof(readmsg.data), type, IPC_NOWAIT);
        if(len > 0) cout <<  "read : " << len << ", data:" << readmsg.data <<  endl;
        else cout << "read fail, type:" << readmsg.type << endl;
        return len > 0;
    }

    void send(int type) {
        sendmsg.type = type;
        sprintf(sendmsg.data, "msg type : %ld",  sendmsg.type);
        int len = strlen(sendmsg.data)+1;
        int ret = msgsnd(msgId, &sendmsg, len, sendmsg.type); // 0 or -1
        if(!ret) {
            cout << "send fail, " << strerror(errno) << endl; //
            return;
        }
        puts("send succeed");
    }

    void test() override {
        if(!valid) return;
        if(flag == 1) send(512);
        else if(flag == 0) read(512);
    }

private:
    int  msgId;
    bool valid;
    my_msg sendmsg, readmsg;

    char flag; // 0:read
};


#endif // MSG_H
